package com.example.controller;

import cn.hutool.core.util.URLUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.common.Result;
import com.example.entity.Notice;
import com.example.service.NoticeService;
import com.github.pagehelper.PageInfo;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

@RestController
@RequestMapping("/notice")
public class NoticeController {

    @Autowired
    private NoticeService noticeService;

    /**
     * 查询所有公告
     * @return 公告列表
     */
    @GetMapping("/selectAll")
    public Result selectAll(Notice notice) {
        List<Notice> notices = noticeService.selectAll(notice);
        return Result.success(notices);
    }

    /**
     * 分页查询公告
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @return 公告分页信息
     */
    @GetMapping("/selectByPage")
    public Result selectByPage(Notice notice, @RequestParam(defaultValue = "1") Integer pageNum,
                               @RequestParam(defaultValue = "10") Integer pageSize) {
        PageInfo<Notice> noticePageInfo = noticeService.selectByPage(notice, pageNum, pageSize);
        return Result.success(noticePageInfo);
    }

    /**
     * 新增公告
     * @param notice 公告信息
     * @return
     */
    @PostMapping("/add")
    public Result add(@RequestBody Notice notice) {
        noticeService.add(notice);
        return Result.success();
    }

    /**
     * 更新公告
     * @param notice 公告信息
     * @return
     */
    @PutMapping("/update")
    public Result update(@RequestBody Notice notice) {
        noticeService.update(notice);
        return Result.success();
    }

    /**
     * 删除公告
     * @param id 公告id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        noticeService.delete(id);
        return Result.success();
    }

    /**
     * 批量导出公告
     * @param response HTTP 响应对象
     * @return
     */
    @GetMapping("/export")
    public void batchImport(HttpServletResponse response) throws Exception {
        // 查询所有公告数据
        List<Notice> notices = noticeService.selectAll(null);

        // 创建 ExcelWriter
        ExcelWriter writer = ExcelUtil.getWriter(true); // true 表示使用 xlsx 格式

        // 设置表头别名（确保字段名与 Notice 实体类一致）
        writer.addHeaderAlias("title", "公告标题");
        writer.addHeaderAlias("content", "公告内容");
        writer.addHeaderAlias("time", "发布时间");

        // 设置日期格式（如果需要）
        writer.setOnlyAlias(true); // 只导出设置了别名的字段

        // 写入数据（true 表示包含表头）
        writer.write(notices, true);

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
        String fileName = URLEncoder.encode("公告数据", StandardCharsets.UTF_8); // 文件名编码
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        // 输出 Excel 文件
        ServletOutputStream outputStream = response.getOutputStream();
        writer.flush(outputStream);

        // 关闭 writer 和输出流
        writer.close();
        outputStream.close();
    }

    /**
     * 批量导入
     */
    @PostMapping("/import")
    public Result batchImport(MultipartFile file) throws Exception {
        // 获取文件输入流
        InputStream inputStream = file.getInputStream();
        // 读取 Excel 文件
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        // 设置表头别名（确保字段名与 Notice 实体类一致）
        reader.addHeaderAlias("公告标题", "title");
        reader.addHeaderAlias("公告内容", "content");
        // 读取数据
        List<Notice> notices = reader.readAll(Notice.class);
        // 写入数据库
        for (Notice notice : notices) {
            noticeService.add(notice);
        }
        return Result.success();
    }
}
